package cc.eguid.tools;

import cc.eguid.tools.msg.*;

import java.io.*;
import java.net.Socket;

/**
 * 文件传输客户端 - 独立连接处理文件传输
 */
public class FileTransferClient {
    private String serverIp;
    private int filePort;
    private Socket fileSocket;
    private ObjectOutputStream out;
    private ObjectInputStream in;
    private String token;

    public FileTransferClient(String serverIp, int filePort, String token) {
        this.serverIp = serverIp;
        this.filePort = filePort;
        this.token = token;
    }

    /**
     * 上传文件到服务器
     * @param file 要上传的文件
     * @param targetPath 目标路径
     * @throws IOException 传输异常
     */
    public void uploadFile(File file, String targetPath) throws IOException {
        if (!file.exists() || !file.isFile()) {
            throw new IOException("文件不存在: " + file.getAbsolutePath());
        }

        try {
            // 建立文件传输连接
            fileSocket = new Socket(serverIp, filePort);
            out = new ObjectOutputStream(fileSocket.getOutputStream());
            in = new ObjectInputStream(fileSocket.getInputStream());

            // 发送令牌进行验证
            out.writeObject(new TokenMessage(token));
            out.flush();

            // 等待服务端验证结果
            Object obj = in.readObject();
            if (obj instanceof AuthMessage) {
                AuthMessage authMsg = (AuthMessage) obj;
                if (!authMsg.isSuccess()) {
                    throw new IOException("文件传输验证失败: " + authMsg.getMessage());
                }
            } else {
                throw new IOException("无效的服务端响应");
            }

            // 发送文件上传请求
            FileUploadMessage uploadRequest = new FileUploadMessage(
                    file.getName(),
                    targetPath,
                    file.length()
            );
            out.writeObject(uploadRequest);
            out.flush();

            // 等待服务端响应
            Object responseObj = in.readObject();
            if (responseObj instanceof FileUploadResponse) {
                FileUploadResponse uploadResponse = (FileUploadResponse) responseObj;
                if (!uploadResponse.isAccepted()) {
                    throw new IOException("服务端拒绝文件上传: " + uploadResponse.getMessage());
                }
            } else {
                throw new IOException("无效的服务端响应");
            }

            // 发送文件数据
            try (FileInputStream fileInputStream = new FileInputStream(file)) {
                byte[] buffer = new byte[8192];
                int bytesRead;
                long totalSent = 0;

                while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                    totalSent += bytesRead;

                    // 每发送1MB数据刷新一次
                    if (totalSent % (1024 * 1024) == 0) {
                        out.flush();
                    }
                }
                out.flush();
            }

            // 等待上传结果
            Object resultObj = in.readObject();
            if (resultObj instanceof FileUploadResult) {
                FileUploadResult uploadResult = (FileUploadResult) resultObj;
                if (!uploadResult.isSuccess()) {
                    throw new IOException("文件上传失败: " + uploadResult.getMessage());
                }
                System.out.println("文件上传成功: " + uploadResult.getMessage());
            } else {
                throw new IOException("无效的服务端响应");
            }

        } catch (ClassNotFoundException e) {
            throw new IOException("协议错误: " + e.getMessage());
        } finally {
            close();
        }
    }

    private void close() {
        try {
            if (in != null) in.close();
            if (out != null) out.close();
            if (fileSocket != null) fileSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

